﻿/*******************************************************************************
*
*	file : jie mi.c
*
*******************************************************************************/
#include "stdint.h" 
#include "stdlib.h" 
#include "string.h" 


/*******************************************************************************
* 数据包格式：
* 每包数据40字节
* 6字节数据头
* 2字节数据开关信息
* 32字节正文
* 仅正文部分加密
*******************************************************************************/

/*- 数据包 数据头 */
static const uint8_t dat_head[6] = { 0xEE, 0xDD, 0xCC, 0xCC, 0xDD, 0xEE };

/*
两字节字节开关，内容相同，
bit[0]-温度
bit[1]-湿度
bit[2]-转速
bit[3]-光照
bit[4]-CO2
bit[5]-O2
bit[6]-压力
*/
typedef union
{
	uint8_t val;
	struct
	{
		uint8_t temp : 1;
		uint8_t humi : 1;
		uint8_t speed : 1;
		uint8_t light : 1;
		uint8_t co2 : 1;
		uint8_t o2 : 1;
		uint8_t press : 1;
	} bit;
} out_en_type;

//- 正文数据结构
typedef union{
	uint32_t val;

	struct {
		uint32_t rs : 2; //0-runing, 1-start
		uint32_t sec8t : 3; // x8 秒
		uint32_t min : 6;
		uint32_t hour : 5;
		uint32_t day : 5;
		uint32_t mon : 4;
		uint32_t year : 7;
	} log;
} sig_time_type;

typedef struct
{
	sig_time_type time;
	int16_t temp_pv;
	int16_t temp_sv;
	int16_t humi_pv;
	int16_t humi_sv;
	int16_t light_pv;
	int16_t light_sv;
	int16_t rpm_pv;
	int16_t rpm_sv;
	int16_t co2_pv;
	int16_t co2_sv;
	int16_t o2_pv;
	int16_t o2_sv;
	int16_t press_pv;
	int16_t press_sv;
} hist_dat_type;

//*- 加密信息表1
static const uint8_t sinx_0r5pi_256_255[] =
{
	0, 2, 3, 5, 6, 8, 9, 11, 13, 14,                                        //Line 1
	16, 17, 19, 20, 22, 24, 25, 27, 28, 30,                                 //Line 2
	31, 33, 34, 36, 38, 39, 41, 42, 44, 45,                                 //Line 3
	47, 48, 50, 51, 53, 55, 56, 58, 59, 61,                                 //Line 4
	62, 64, 65, 67, 68, 70, 71, 73, 74, 76,                                 //Line 5
	77, 79, 80, 82, 83, 85, 86, 88, 89, 91,                                 //Line 6
	92, 94, 95, 96, 98, 99, 101, 102, 104, 105,                             //Line 7
	107, 108, 109, 111, 112, 114, 115, 116, 118, 119,                       //Line 8
	121, 122, 123, 125, 126, 128, 129, 130, 132, 133,                       //Line 9
	134, 136, 137, 138, 140, 141, 142, 143, 145, 146,                       //Line 10
	147, 149, 150, 151, 152, 154, 155, 156, 157, 159,                       //Line 11
	160, 161, 162, 164, 165, 166, 167, 168, 169, 171,                       //Line 12
	172, 173, 174, 175, 176, 178, 179, 180, 181, 182,                       //Line 13
	183, 184, 185, 186, 187, 188, 190, 191, 192, 193,                       //Line 14
	194, 195, 196, 197, 198, 199, 200, 201, 202, 203,                       //Line 15
	203, 204, 205, 206, 207, 208, 209, 210, 211, 212,                       //Line 16
	213, 213, 214, 215, 216, 217, 218, 218, 219, 220,                       //Line 17
	221, 222, 222, 223, 224, 225, 225, 226, 227, 228,                       //Line 18
	228, 229, 230, 230, 231, 232, 232, 233, 234, 234,                       //Line 19
	235, 235, 236, 237, 237, 238, 238, 239, 239, 240,                       //Line 20
	241, 241, 242, 242, 243, 243, 243, 244, 244, 245,                       //Line 21
	245, 246, 246, 247, 247, 247, 248, 248, 248, 249,                       //Line 22
	249, 249, 250, 250, 250, 251, 251, 251, 251, 252,                       //Line 23
	252, 252, 252, 253, 253, 253, 253, 253, 254, 254,                       //Line 24
	254, 254, 254, 254, 254, 255, 255, 255, 255, 255,                       //Line 25
	255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
};

/****************************************************************************
 * 字内 半字节交换
 * **************************************************************************/
static void swap_u32_with_u4(void *p_src, void *p_des, uint16_t Len)
{
	uint32_t temp;
	uint32_t * psrc, *pdes;

	psrc = (uint32_t *)p_src;
	pdes = (uint32_t *)p_des;
	while (Len--)
	{
		temp = *psrc++;
		temp = ((temp & 0xF0000000UL) >> 28) | ((temp & 0x0F000000UL) >> 20) | ((temp & 0x00F00000UL) >> 12) | ((temp & 0x000F0000UL) >> 4)
			| ((temp & 0x0000F000UL) << 4) | ((temp & 0x00000F00UL) << 12) | ((temp & 0x000000F0UL) << 20) | ((temp & 0x0000000FUL) << 28);
		*pdes++ = temp;
	}
}

static void map_add_u8(uint8_t *src1, uint8_t *src2, uint8_t *des, uint32_t len)
{
	while (len--)
	{
		*des++ = (*src1++) + (*src2++);
	}
}

static void map_sub_u8(uint8_t *src1, uint8_t *src2, uint8_t *des, uint32_t len)
{
	while (len--)
	{
		*des++ = (*src1++) - (*src2++);
	}
}

/*******************************************************************************
* @brief  解密数据包
* \param[in] dat : 指针 -> 一包数据的首地址 (每包40字节)
* \retval: 错误信息
*******************************************************************************/
uint8_t yh_dat_jie_mi(uint8_t *dat)
{
	out_en_type out_en;
	hist_dat_type hist_dat;
	uint16_t hist_size = 32;

	// 数据头验证
	if (0 != memcmp(dat_head, dat, 6))
		return 1;

	if (dat[6] != dat[7])
		return 2;

	if (dat[6] == 0)
		return 3;

	out_en.val = dat[6];

	////////////////////////////////////////////////////////////////////////////
	////////////////////////////////////////////////////////////////////////////

	// 解密
	map_sub_u8((uint8_t *)&dat[8],
		(uint8_t *)sinx_0r5pi_256_255,
		(uint8_t *)&hist_dat, hist_size);

	swap_u32_with_u4(&hist_dat, &hist_dat, hist_size >> 2);

	////////////////////////////////////////////////////////////////////////////
	////////////////////////////////////////////////////////////////////////////

	// 输出
	(void)hist_dat.time.val;
	//时间输出

	if (out_en.bit.temp)
	{
		(void)hist_dat.temp_pv;
		(void)hist_dat.temp_sv;
		// 温度输出
	}

	if (out_en.bit.humi)
	{
		(void)hist_dat.humi_pv;
		(void)hist_dat.humi_sv;
		// 湿度输出
	}

	if (out_en.bit.speed)
	{
		(void)hist_dat.rpm_pv;
		(void)hist_dat.rpm_sv;
		// 转速输出
	}

	if (out_en.bit.light)
	{
		(void)hist_dat.light_pv;
		(void)hist_dat.light_sv;
		// 光照输出
	}

	if (out_en.bit.co2)
	{
		(void)hist_dat.co2_pv;
		(void)hist_dat.co2_sv;
		// CO2输出
	}

	if (out_en.bit.o2)
	{
		(void)hist_dat.o2_pv;
		(void)hist_dat.o2_sv;
		// O2输出
	}

	if (out_en.bit.press)
	{
		(void)hist_dat.press_pv;
		(void)hist_dat.press_sv;
		// 压力 输出
	}

	return 0;
}





